import { shallowRef } from 'vue'

interface WebsocketCallback<T = any> {
  onopen?: WebSocket['onopen']
  onerror?: WebSocket['onerror']
  // onmessage?: WebSocket['onmessage']
  onmessage?: (data: T, e: MessageEvent<any>) => void
  onclose?: WebSocket['onclose']
}

/**
 * websocket链接
 * @param url WebSocket['url'] 建立连接地址
 * @param websocketCallback WebsocketCallback websocket必要的事件配置
 * @param protocol WebSocket['protocol'] websocket配置协议
 */
export default function (
  url: WebSocket['url'],
  websocketCallback: WebsocketCallback,
  protocol?: WebSocket['protocol']
) {
  const webSocketRef = shallowRef<WebSocket>()

  const initWebsocket = () => {
    const websocket = new WebSocket(`ws://${location.host}${url}`, protocol)

    // websocket连接建立回调
    websocket.onopen = websocketCallback?.onopen || (() => {})

    // websocket连接建立失败重连
    websocket.onerror =
      websocketCallback?.onerror ||
      (() => {
        initWebsocket()
      })

    // websocket数据接收
    websocket.onmessage = (e) => {
      if (!websocketCallback.onmessage) return
      const data = JSON.parse(e.data)
      window.swInitFun(data)
      websocketCallback.onmessage(data, e)
    }

    // websocket关闭
    websocket.onclose =
      websocketCallback?.onclose ||
      (() => {
        webSocketRef.value?.close()
      })

    webSocketRef.value = websocket
  }

  initWebsocket()

  return webSocketRef
}
